package com.hsgene.order.controller.doctor;

import com.hsgene.common.util.check.ObjectAttrUtils;
import com.hsgene.common.util.exception.ErrorCode;
import com.hsgene.common.util.result.ApiResult;
import com.hsgene.common.util.result.PeanutApiResult;
import com.hsgene.order.constants.DoctorType;
import com.hsgene.order.domain.disease.GeneticDisease;
import com.hsgene.order.domain.reserve.GeneticPatient;
import com.hsgene.order.domain.reserve.ReserveOrderInfoDto;
import com.hsgene.order.domain.reserve.ReserveOrderResultDto;
import com.hsgene.order.domain.reserve.product.GeneticTestingProductDto;
import com.hsgene.order.domain.reserve.product.ProductCancers;
import com.hsgene.order.dto.doctor.OrderLogisticsInfoDto;
import com.hsgene.order.dto.doctor.OrderProductLogisticsInfoDto;
import com.hsgene.order.exception.ObjectAttributeInfoEnum;
import com.hsgene.order.exception.OrderErrorCode;
import com.hsgene.order.service.OrderService;
import com.hsgene.order.service.ReserveOrderService;
import com.hsgene.order.service.UserAuthenticationService;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 金琉璃医生订单接口
 *
 * @author wxf
 * @date 2018/9/17 14:06
 **/
@RestController
@RequestMapping("/v1.0/genetic/testing")
public class DoctorOrderController {
    /**
     * Log
     */
    private static Logger LOGGER = LogManager.getLogger(DoctorOrderController.class);

    @Resource
    private OrderService orderService;

    @Resource
    private ReserveOrderService reserveOrderService;

    @Resource
    private UserAuthenticationService userService;

    /**
     * 获取疾病列表
     *
     * @param userId 用户id
     * @return
     */
    @GetMapping("disease")
    public PeanutApiResult<List<GeneticDisease>> getGeneticDisease(String userId) {
        try {
            if (StringUtils.isEmpty(userId)) {
                return PeanutApiResult.defaultFail(OrderErrorCode.USER_IS_NOT_NULL);
            }
            List<GeneticDisease> diseaseList = reserveOrderService.getGeneticDisease();
            return PeanutApiResult.resultValue(diseaseList, 200, true, System.currentTimeMillis());
        } catch (Exception e) {
            LOGGER.error("get disease is error", e);
            return PeanutApiResult.defaultFail(OrderErrorCode.QUERY_DISEASE_IS_ERROR);
        }
    }

    /**
     * 医生预约下单-金琉璃下单接口
     *
     * @param orderInfoDto 订单信息
     * @return
     */
    @PostMapping("orders/doctor")
    public ApiResult<Object> doctorAddOrder(@RequestBody ReserveOrderInfoDto orderInfoDto) {
        try {
            //校验信息是否为null
            ErrorCode checkResult = checkParamsIsNull(orderInfoDto);
            if (checkResult != null) {
                return ApiResult.fail(checkResult);
            }
            //校验用户是否合格
            Map<String, Object> doctorMap = userService.userAuthVerify(orderInfoDto.getUserId());
            if (doctorMap == null || StringUtils.isEmpty((String) doctorMap.get("auth"))) {
                return ApiResult.fail(OrderErrorCode.DOCOTOR_ID_IS_NOT_EXIST);
            }
            //状态1表示医生可用
            if (!DoctorType.ONE.getCode().equals(doctorMap.get("auth"))) {
                return ApiResult.fail(OrderErrorCode.DOCOTOR_STATUS_ERROR);
            }
            //开始下单时间
            Date date = new Date();
            ReserveOrderResultDto resultDto = reserveOrderService.doctorAddOrder(orderInfoDto, date, doctorMap);
            if (StringUtils.isEmpty(resultDto.getOrderNo())) {
                return ApiResult.fail(OrderErrorCode.PACKAGEID_NOT_EXISTS);
            }
            return ApiResult.succ(resultDto, "下单成功");
        } catch (Exception e) {
            LOGGER.error("Add Order is error", e);
            return ApiResult.fail(OrderErrorCode.ADD_ORDER_IS_ERROR);
        }
    }

    /**
     * 获取订单套餐物流
     *
     * @param orderId   订单id
     * @param productId 套餐id
     * @return
     */
    @GetMapping("orders/commodities/logistics")
    public ApiResult<OrderProductLogisticsInfoDto> getOrderProductLogistics(String orderId, String productId) {
        try {
            if (StringUtils.isEmpty(orderId)) {
                return ApiResult.fail(OrderErrorCode.ORDER_ID_IS_NOT_NULL);
            }
            if (StringUtils.isEmpty(productId)) {
                return ApiResult.fail(OrderErrorCode.PRODUCT_ID_IS_NOT_NULL);
            }
            OrderProductLogisticsInfoDto logisticsInfoDto = orderService.getOrderProductLogistics(orderId, productId);
            if (logisticsInfoDto == null) {
                return ApiResult.fail(OrderErrorCode.PACKAGEID_NOT_EXISTS);
            }
            return new ApiResult<>(200, "success", "查询套餐物流成功", logisticsInfoDto);
        } catch (Exception e) {
            LOGGER.error("query logistics is error", e);
            return ApiResult.fail(OrderErrorCode.EXPRESS_IS_ERROR);
        }
    }

    /**
     * 获取订单物流信息
     *
     * @param orderId 订单id
     * @return
     */
    @GetMapping("orders/{order_id}/logistics")
    public ApiResult getLogisticsDetail(@PathVariable("order_id") String orderId) {
        try {
            if (StringUtils.isEmpty(orderId)) {
                return ApiResult.fail(OrderErrorCode.ORDER_ID_IS_NOT_NULL);
            }
            //
            Integer flag = orderService.checkOrderStatus(orderId, null);
            if (flag == null) {
                return ApiResult.fail(OrderErrorCode.ORDER_STATUS_EXCEPTION);
            }
            List<OrderLogisticsInfoDto> logisticsInfoDtos = orderService.getLogisticsDetail(orderId);
            return new ApiResult(200, "success", "查询套餐物流成功", logisticsInfoDtos);
        } catch (Exception e) {
            LOGGER.error("query logistics is error", e);
            return ApiResult.fail(OrderErrorCode.EXPRESS_IS_ERROR);
        }
    }

    /**
     * 校验参数不为null
     *
     * @param orderInfoDto 下单信息
     * @return
     */
    private ErrorCode checkParamsIsNull(ReserveOrderInfoDto orderInfoDto) {
        if (orderInfoDto == null) {
            return OrderErrorCode.DATA_INFO_IS_NOT_NULL;
        }
        ErrorCode orderParams = getParamsCheckResultCode(orderInfoDto, "remark");
        if (orderParams != null) {
            return orderParams;
        }
        //套餐
        List<GeneticTestingProductDto> productDtos = orderInfoDto.getProducts();
        if (productDtos == null || productDtos.isEmpty()) {
            return OrderErrorCode.PRODUCT_IS_NOT_NULL;
        }
        for (GeneticTestingProductDto productDto : productDtos) {
            if (StringUtils.isEmpty(productDto.getProductId())) {
                return OrderErrorCode.PRODUCT_IS_NOT_NULL;
            }
        }
        //患者信息
        GeneticPatient patient = orderInfoDto.getPatient();
        if (patient == null) {
            return OrderErrorCode.PATIENT_IS_NOT_NULL;
        }
        if (StringUtils.isEmpty(patient.getPatientName())) {
            return OrderErrorCode.PATIENT_NAME_IS_NOT_NULL;
        }
        //疾病信息
        ErrorCode errorCode = checkDiseaseParams(orderInfoDto.getCancers());
        if (errorCode != null) {
            return errorCode;
        }
        return null;
    }

    private ErrorCode getParamsCheckResultCode(Object object, String... excludeField) {
        List<Object> excludeFields = ObjectAttrUtils.getExcludeObjectFields(excludeField);
        String result = ObjectAttrUtils.checkObjectAttrIsNull(object, excludeFields);
        if (StringUtils.isNotEmpty(result)) {
            return ObjectAttributeInfoEnum.getEnum(result);
        }
        return null;
    }

    private ErrorCode checkDiseaseParams(List<ProductCancers> cancers) {
        if (cancers == null || cancers.isEmpty()) {
            return OrderErrorCode.PATIENT_CANCERS_IS_NOT_NULL;
        }
        for (ProductCancers cancer : cancers) {
            String result = ObjectAttrUtils.checkObjectAttrIsNull(cancer, null);
            if (StringUtils.isNotEmpty(result)) {
                //ProductCancers只有2个字段
                result = result.equals("category") ? "diseaseType" : "id";
                return ObjectAttributeInfoEnum.getEnum(result);
            }
        }
        return null;
    }

    /**
     * 查看报告
     *
     * @param reportName 文件名称
     * @param userId     用户ID-医生用户id
     * @return
     */
    @GetMapping("orders/report")
    public ApiResult<String> getOrderReport(
            @RequestParam("reportName") String reportName,
            @RequestParam("userId") String userId) {
        return orderService.queryOrderPackageReport(userId, reportName);
    }
}
